package com.h2View.controller;

import com.h2View.entity.TableData;
import com.h2View.utils.CacheUtil;
import com.h2View.utils.MybatisUtils;
import com.h2View.utils.StringUtil;
import com.h2View.utils.ToolConstant;
import com.h2View.utils.ToolUtil;
import com.xjw.annotation.FXController;
import com.xjw.annotation.FXRedirect;
import com.xjw.annotation.FXWindow;
import com.xjw.entity.FXBaseController;

import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.util.StringConverter;

import java.net.URL;
import java.util.LinkedHashMap;
import java.util.ResourceBundle;


/**
 * @author xwx1052336
 * @since iFad Platform V100R001,2021/9/8
 */
@FXController(path = "fxml/data.fxml")
@FXWindow(title = "数据操作页面", icon = "image/icon.png")
public class DataController extends FXBaseController implements Initializable {

    @FXML
    private TableView<TableData> dataEle;

    private String tableName;

    private TableData editingData;

    private String type;

    private ObservableList<TableData> dataList = FXCollections.observableArrayList();

    private ObservableList<TableData> oldDataList = FXCollections.observableArrayList();
    private ObservableList<TableData> editingDataList = FXCollections.observableArrayList();

    private FunctionController functionController;

    public static boolean flag = false;

    private Log log = LogFactory.get();

    @Override
    public void onShow() {
        dataList.clear();
        oldDataList.clear();
        editingDataList.clear();
        type = CacheUtil.get("type");
        LinkedHashMap<String,Object> data =  CacheUtil.get("dataController");
        tableName = CacheUtil.get("tableName");
        functionController = CacheUtil.get("FunctionController");
        if(data!=null){
            for(String key:data.keySet()){
                TableData tableData = new TableData();
                tableData.setName(key);
                if(ToolConstant.CREATEDATA.equals(type)){
                    tableData.setValue("");
                }else if(ToolConstant.UPDATEDATA.equals(type)){
                    tableData.setValue(data.get(key));
                }
                dataList.add(tableData);
                oldDataList.add(copyValue(tableData));
                editingDataList.add(copyValue(tableData));
            }
        }
       ToolUtil.execAsync(()->flag = true,1000);
    }

    private TableData copyValue(TableData tableData){
        TableData tableDataNew = new TableData();
        tableDataNew.setName(tableData.getName());
        tableDataNew.setValue(tableData.getValue());
        return tableDataNew;
    }

    @SuppressWarnings("unchecked")
    @Override
    public void initialize(URL location, ResourceBundle resources) {
        log.info("----------------init DataController---------------");
        TableColumn<TableData,Object> valueColumn = new TableColumn<>();
        valueColumn.setEditable(true);
        valueColumn.setMinWidth(100);
        valueColumn.setCellValueFactory(new PropertyValueFactory("value"));
        valueColumn.setCellFactory(p -> {
            TextFieldTableCell<TableData,Object> cell = new TextFieldTableCell<>(new StringConverter() {
                @Override
                public String toString(Object object) {
                    if(object != null){
                        return object.toString();
                    }
                    return null;
                }

                @Override
                public Object fromString(String string) {
                    if(StringUtil.isNumeric(string)){
                        return Integer.parseInt(string);
                    }
                    return string;
                }
            });
            cell.textProperty().addListener((observable, oldValue, newValue) -> {
                if( !cell.isEditing() && flag ){
                    if(editingData == null||equals(newValue,editingData.getValue())){
                        return;
                    }
                    changeValue(newValue,editingData);
                }else{
                    editingData = dataEle.getSelectionModel().getSelectedItem();
                }
            });

            return cell;
        });
        valueColumn.setText("值");
        dataEle.getColumns().add(valueColumn);
        dataEle.setItems(dataList);
        dataEle.setEditable(true);
        flag = true;
    }

    private boolean equals(Object src,Object dest){
        if(src == null && dest == null){
            return true;
        }else if(src == null){
            return false;
        }
        if(dest instanceof Integer){
            try{
                return dest.equals(Integer.parseInt(src.toString()));
            }catch (Exception e){
                return false;
            }
        }
        return src.equals(dest);
    }

    private void changeValue(String newValue,TableData tableData){
        int index = editingDataList.indexOf(tableData);
        if(editingData.getValue() instanceof Integer && StringUtil.isNotEmpty(newValue)){
            tableData.setValue(Integer.parseInt(newValue));
        }else{
            tableData.setValue(newValue);
        }
        editingDataList.set(index,tableData);
    }

    @FXML
    @FXRedirect
    public String sava(){
        String sql;
        if(ToolConstant.CREATEDATA.equals(type)){
             sql = getCreateSql();
        }else if(ToolConstant.UPDATEDATA.equals(type)){
            sql = getUpdateSql();
        }else{
            return "DataController";
        }
        if(ToolUtil.excute(sql)){
            MybatisUtils.reLoadSession();
            functionController.showTableData();
            return "FunctionController";
        }else{
            return "DataController";
        }

    }

    private String getCreateSql(){
        StringBuilder sql = new StringBuilder("insert into " + tableName + "( ");
        for(TableData tableData:editingDataList){
            sql.append(tableData.getName()).append(",");
        }
        ToolUtil.deleteLast(sql);
        sql.append(") VALUES (");
        for(TableData tableData:editingDataList){
            Object value = tableData.getValue();
            if(value instanceof Integer){
                sql.append(value).append(",");
            }else{
                sql.append("'").append(value).append("'").append(",");
            }
        }
        ToolUtil.deleteLast(sql);
        sql.append(");");
        return sql.toString();
    }

    private String getUpdateSql(){
        StringBuilder sql = new StringBuilder("update " + tableName + " set ");
        for(TableData tableData:editingDataList){
            if(tableData.getValue() instanceof Integer){
                sql.append(" ").append(tableData.getName()).append(" = ").append(tableData.getValue()).append(" ,");
            }else if(tableData.getValue() instanceof String){
                sql.append(" ").append(tableData.getName()).append(" = '").append(tableData.getValue()).append("' ,");
            }
        }
        ToolUtil.deleteLast(sql);
        sql.append(" where ");
        for(TableData tableData:oldDataList){
            if(StringUtil.isEmpty(tableData.getValue())){
                continue;
            }
            if(tableData.getValue() instanceof Integer){
                sql.append(" ").append(tableData.getName()).append(" = ").append(tableData.getValue()).append(" and");
            }else if(tableData.getValue() instanceof String){
                sql.append(" ").append(tableData.getName()).append(" = '").append(tableData.getValue()).append("' and");
            }
        }
        ToolUtil.deleteLast(sql,3);
        return sql.toString();
    }

    @FXML
    @FXRedirect
    public String close(){
        return "FunctionController";
    }

}
